home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / hity wydania / Ubuntu 9.10 PL / karmelkowy-koliberek-desktop-9.10-i386-PL.iso / casper / filesystem.squashfs / usr / share / laptop-mode-tools / modules / laptop-mode < prev    next >
Text File  |  2009-10-06  |  15KB  |  413 lines

  1. #! /bin/sh
  2. #
  3. # Laptop mode tools module: core laptop mode functionality
  4. #
  5.  
  6.  
  7.  
  8.  
  9. # Remove an option (the first parameter) of the form option=<number> from
  10. # a mount options string (the rest of the parameters).
  11. remove_numeric_mount_option () {
  12.     OPT="$1"
  13.     shift
  14.     echo ",$*," | sed        \
  15.      -e 's|,'"$OPT"'=[0-9]*,|,|g'    \
  16.      -e 's/,,*/,/g'            \
  17.      -e 's/^,//'            \
  18.      -e 's/,$//'
  19. }
  20.  
  21. # Remove an option (the first parameter) without any arguments from
  22. # a mount option string (the rest of the parameters).
  23. remove_fixed_mount_option () {
  24.     OPT="$1"
  25.     shift
  26.     echo ",$*," | sed        \
  27.      -e 's|,'"$OPT"',|,|g'        \
  28.      -e 's/,,*/,/g'            \
  29.      -e 's/^,//'            \
  30.      -e 's/,$//'
  31. }
  32.  
  33. # Find out the state of an atime option ("atime"/"noatime"/"relatime"/"norelatime")
  34. # in a set of mount options, and use this state to replace the value of the
  35. # option in another mount options string.
  36. #
  37. # Example:
  38. # replace_atime_mount_option defaults,user=1000,atime defaults,noatime
  39. #
  40. # This yields "defaults,atime".
  41. replace_atime_mount_option () {
  42.     REPLACEMENT_OPTS="$1"
  43.     OPTS="$2"
  44.     PARSEDOPTS="$(remove_fixed_mount_option atime $OPTS)"
  45.     PARSEDOPTS="$(remove_fixed_mount_option noatime $PARSEDOPTS)"
  46.     PARSEDOPTS="$(remove_fixed_mount_option relatime $PARSEDOPTS)"    
  47.     PARSEDOPTS="$(remove_fixed_mount_option norelatime $PARSEDOPTS)"    
  48.  
  49.     case ",$REPLACEMENT_OPTS," in
  50.     *",relatime,"*)
  51.         echo "$PARSEDOPTS,relatime"
  52.         ;;
  53.     *",noatime,"*)
  54.         echo "$PARSEDOPTS,noatime"
  55.         ;;
  56.     *)
  57.         # Kind of strange: to go from relatime to atime, we have to
  58.         # explicitly specify norelatime.
  59.          echo "$PARSEDOPTS,atime,norelatime"
  60.          ;;
  61.     esac
  62. }
  63.  
  64. # Find out the state of a numbered option (e.g. "commit=NNN") in
  65. # a set of options, and use this state to replace the
  66. # value of the option in another mount options string. 
  67. #
  68. # Example:
  69. # replace_numeric_mount_option commit defaults,user=1000,commit=3 defaults,commit=7
  70. #
  71. # This example yields "defaults,commit=3".
  72. replace_numeric_mount_option () {
  73.     OPT="$1"
  74.     DEF_OPT="$2"
  75.     REPLACEMENT_OPTS="$3"
  76.     OPTS="$4"    
  77.     PARSEDOPTS="$(remove_numeric_mount_option $OPT $OPTS)"
  78.     
  79.     if echo ",$REPLACEMENT_OPTS," | grep ",$OPT=[0123456789]+," > /dev/null ; then
  80.         echo -n "$PARSEDOPTS,$OPT="
  81.         echo ",$REPLACEMENT_OPTS," | sed \
  82.          -e 's/.*,'"$OPT"'=//'    \
  83.          -e 's/,.*//'
  84.     else
  85.         # Option not present in REPLACEMENT_OPTS: use the default.
  86.         echo "$PARSEDOPTS,$DEF_OPT"
  87.     fi
  88. }
  89.  
  90. deduce_fstype () {
  91.     MP="$1"
  92.     # My root filesystem unfortunately has type "unknown" in
  93.     # /etc/mtab. If we encounter "unknown", we try to get the
  94.     # type from fstab. This still might be wrong, in which
  95.     # case the code further down will issue a big warning.
  96.     sed 's/[[:space:]]*#.*$//' /etc/fstab |
  97.     while read FSTAB_DEV FSTAB_MP FSTAB_FST FSTAB_OPTS FSTAB_DUMP FSTAB_DUMP ; do
  98.         if [ "$FSTAB_MP" = "$MP" ]; then
  99.             echo "$FSTAB_FST"
  100.             exit 0
  101.         fi
  102.     done
  103. }
  104.  
  105.  
  106. #
  107. # Set kernel setting, showing an error if this fails.
  108. #
  109. # Parameter 1: sysctl/proc path
  110. # Parameter 2: the value
  111. #
  112. set_sysctl() {
  113.     $LM_VERBOSE && echo "Executing: echo $2 > $1" >> $OUTPUT
  114.     if ! echo "$2" > "$1" ; then
  115.         echo "SETTING OF KERNEL PARAMETER FAILED: echo $2 \> $1"
  116.     fi
  117. }
  118.  
  119.  
  120. if [ "$CONTROL_READAHEAD" -ne 0 ] ; then
  121.     if /sbin/blockdev --help 2>&1 | grep -Fq -- '--setfra' ; then
  122.         READAHEAD_OPTION=--setfra                    
  123.     else
  124.         READAHEAD_OPTION=--setra
  125.         if [ "$KLEVEL" = "2.4" ] ; then
  126.             echo "Warning: Running a 2.4 kernel with blockdev that does not support --setfra."
  127.             echo "File system readahead will not function properly."
  128.         fi
  129.     fi
  130. fi
  131.  
  132.  
  133.  
  134. if [ $CONTROL_NOATIME -eq 1 ] ; then
  135.     if [ "$KLEVEL" = "2.4" ] ; then
  136.         $LM_VERBOSE && echo "Relatime is not supported on 2.4 kernels. Using noatime instead" >> $OUTPUT 
  137.         USE_RELATIME=0
  138.     elif [ "$KLEVEL" = "2.6" -a "$KMINOR" -lt 23 ] ; then
  139.         $LM_VERBOSE && echo "Relatime is not supported on kernels before 2.6.23. Using noatime instead." >> $OUTPUT
  140.         USE_RELATIME=0
  141.     fi
  142.     if [ "$USE_RELATIME" = 1 ] ; then
  143.         NOATIME_OPT=",relatime"
  144.     else
  145.         NOATIME_OPT=",noatime"
  146.     fi
  147. fi
  148.  
  149.  
  150. # Adjust kernel settings and mount options (but only if data loss 
  151. # sensitive features are active)
  152. if [ "$ACTIVATE_WITH_POSSIBLE_DATA_LOSS" -eq 1 ] ; then
  153.     # Take MAX_LOST_WORK_SECONDS from LM_BATT_MAX_LOST_WORK_SECONDS or LM_AC_MAX_LOST_WORK_SECONDS_WITH_LM, depending on power state.
  154.     MAX_LOST_WORK_SECONDS=$LM_BATT_MAX_LOST_WORK_SECONDS
  155.     if [ $ON_AC -eq 1 ] ; then
  156.         MAX_LOST_WORK_SECONDS=$LM_AC_MAX_LOST_WORK_SECONDS
  157.     fi
  158.  
  159.     AGE=$((100*$MAX_LOST_WORK_SECONDS))
  160.     XFS_AGE=$(($XFS_HZ*$MAX_LOST_WORK_SECONDS))
  161.  
  162.     if [ -d /proc/sys/vm/pagebuf ] ; then
  163.         # (For 2.4 and early 2.6.)
  164.         # This only needs to be set, not reset -- it is only used when
  165.         # laptop mode is enabled.
  166.         $LM_VERBOSE && echo "Adjusting XFS kernel parameters for 2.4 and early 2.6 kernels." >> $OUTPUT
  167.         set_sysctl /proc/sys/vm/pagebuf/lm_flush_age  $XFS_AGE
  168.         set_sysctl /proc/sys/fs/xfs/lm_sync_interval  $XFS_AGE
  169.     elif [ -f /proc/sys/fs/xfs/lm_age_buffer ] ; then
  170.         # (A couple of early 2.6 laptop mode patches had these.)
  171.         # This only needs to be set, not reset -- it is only used when
  172.         # laptop mode is enabled.
  173.         $LM_VERBOSE && echo "Adjusting XFS kernel parameters for early patched 2.6 kernels." >> $OUTPUT
  174.         set_sysctl /proc/sys/fs/xfs/lm_age_buffer    $XFS_AGE
  175.         set_sysctl /proc/sys/fs/xfs/lm_sync_interval $XFS_AGE
  176.     elif [ -f /proc/sys/fs/xfs/age_buffer ] ; then
  177.         # (2.6.6)
  178.         # But not for these -- they are also used in normal
  179.         # operation.
  180.         $LM_VERBOSE && echo "Adjusting XFS kernel parameters for 2.6.6 kernel." >> $OUTPUT
  181.         set_sysctl /proc/sys/fs/xfs/age_buffer       $XFS_AGE 
  182.         set_sysctl /proc/sys/fs/xfs/sync_interval    $XFS_AGE
  183.     elif [ -f /proc/sys/fs/xfs/age_buffer_centisecs ] ; then
  184.         # (2.6.7 upwards)
  185.         # And not for these either. These are in centisecs,
  186.         # not USER_HZ, so we have to use $AGE, not $XFS_AGE.
  187.         $LM_VERBOSE && echo "Adjusting XFS kernel parameters for >2.6.7 kernel." >> $OUTPUT
  188.         set_sysctl /proc/sys/fs/xfs/age_buffer_centisecs  $AGE
  189.         set_sysctl /proc/sys/fs/xfs/xfssyncd_centisecs    $AGE
  190.         set_sysctl /proc/sys/fs/xfs/xfsbufd_centisecs     3000
  191.     fi
  192.  
  193.     case "$KLEVEL" in
  194.         "2.4")
  195.             $LM_VERBOSE && echo "Adjusting 2.4 kernel parameters to enable laptop mode." >> $OUTPUT
  196.             set_sysctl /proc/sys/vm/laptop_mode   1
  197.             set_sysctl /proc/sys/vm/bdflush       "30 500 0 0 $AGE $AGE 60 20 0"
  198.             ;;
  199.         "2.6")
  200.             $LM_VERBOSE && echo "Adjusting 2.6 kernel parameters to enable laptop mode." >> $OUTPUT
  201.             set_sysctl /proc/sys/vm/laptop_mode          "$LM_SECONDS_BEFORE_SYNC"
  202.             set_sysctl /proc/sys/vm/dirty_writeback_centisecs "$AGE"
  203.             set_sysctl /proc/sys/vm/dirty_expire_centisecs    "$AGE"
  204.             set_sysctl /proc/sys/vm/dirty_ratio          "$LM_DIRTY_RATIO"
  205.             set_sysctl /proc/sys/vm/dirty_background_ratio    "$LM_DIRTY_BACKGROUND_RATIO"
  206.             ;;
  207.     esac
  208.     if [ $CONTROL_MOUNT_OPTIONS -eq 1 ]; then
  209.         $LM_VERBOSE && echo "Remounting filesystems." >> $OUTPUT
  210.         cat /etc/mtab | while read DEV MP FST OPTS DUMP PASS ; do
  211.             case "$FST" in 
  212.                 rootfs|unionfs|tmpfs|squashfs|sysfs|usbfs|proc|devpts)
  213.                       continue
  214.                     ;;
  215.             esac
  216.                     
  217.             DO=0
  218.             
  219.             case " $PARTITIONS " in
  220.                 *" $DEV "*)
  221.                     DO=1
  222.                     $LM_VERBOSE && echo "$DEV found in PARTITIONS." >> $OUTPUT
  223.                     ;;
  224.                 *)
  225.                     $LM_VERBOSE && echo "$DEV not found in PARTITIONS." >> $OUTPUT
  226.                     ;;
  227.             esac
  228.             case " $PARTITIONS " in
  229.                 *" $MP "*)
  230.                     DO=1
  231.                     $LM_VERBOSE && echo "$MP found in PARTITIONS." >> $OUTPUT
  232.                     ;;
  233.                 *)
  234.                     $LM_VERBOSE && echo "$MP not found in PARTITIONS." >> $OUTPUT
  235.             esac
  236.             case " $PARTITIONS " in
  237.                 *" auto "*)
  238.                     $LM_VERBOSE && echo "Checking $DEV against HD because PARTITIONS contains \"auto\"." >> $OUTPUT
  239.                     for THISHD in $HD ; do
  240.                         $LM_VERBOSE && echo "   Considering $THISHD." >> $OUTPUT
  241.                         case " $DEV" in *"$THISHD"*)
  242.                             DO=1
  243.                             $LM_VERBOSE && echo "   $DEV contains $THISHD, which is in HD, so we will remount it." >> $OUTPUT
  244.                             break
  245.                             ;;
  246.                         esac
  247.                     done
  248.                     ;;
  249.             esac
  250.             if [ "$DO" -ne 0 ] ; then
  251.                 $LM_VERBOSE && echo "Original options: $OPTS" >> $OUTPUT
  252.                 if [ "$WAS_ACTIVE" -eq 0 ] ; then
  253.                     # Coming from inactive state: save last known mount options for the device.
  254.                     $LM_VERBOSE && echo "Updating /var/run/laptop-mode-tools/nolm-mountopts."  >> $OUTPUT
  255.                     if [ -f /var/run/laptop-mode-tools/nolm-mountopts ] ; then 
  256.                         sed -i "s|^$DEV .*$||" /var/run/laptop-mode-tools/nolm-mountopts
  257.                     fi
  258.                     echo $DEV $OPTS >> /var/run/laptop-mode-tools/nolm-mountopts
  259.                 else
  260.                     $LM_VERBOSE && echo "Not updating /var/run/laptop-mode-tools/nolm-mountopts because laptop mode was already active." >> $OUTPUT
  261.                 fi
  262.                 if [ "$FST" = 'unknown' ]; then
  263.                     $LM_VERBOSE && echo "Deducing fstype for $MP." >> $OUTPUT
  264.                     FST=$(deduce_fstype $MP)
  265.                     $LM_VERBOSE && echo "Deduced fstype for $MP as $FST." >> $OUTPUT
  266.                 fi
  267.                 # Strip stuff like ext3,ext2 into just ext3.
  268.                 $LM_VERBOSE && echo "Reducing file system type."  >> $OUTPUT
  269.                 FST=${FST%%,*}
  270.                 case "$FST" in
  271.                     "ext3"|"reiserfs"|"ext4dev"|"ext4")
  272.                         $LM_VERBOSE && echo "Removing commit mount option from original options."  >> $OUTPUT
  273.                         PARSEDOPTS="$(remove_numeric_mount_option commit "$OPTS")"
  274.                         $LM_VERBOSE && echo "Executing: mount $DEV $MP -t $FST -o remount,$PARSEDOPTS,commit=$MAX_LOST_WORK_SECONDS$NOATIME_OPT" >> $OUTPUT
  275.                         if (! mount $DEV $MP -t $FST -o remount,$PARSEDOPTS,commit=$MAX_LOST_WORK_SECONDS$NOATIME_OPT) ; then
  276.                             if [ "$FST" = "ext3" -a "$MP" = "/" ] ; then
  277.                                 echo "BIG FAT WARNING: Your root filesystem mounted as ext3 seems to lack support for"
  278.                                 echo "the commit mount option. This usually means that your root filesystem is"
  279.                                 echo "mounted as ext2 because there is no ext3 support in the kernel at boot time,"
  280.                                 echo "usually because you compiled ext3 as a module and don't load it in an initrd."
  281.                                 echo "Note that on recent 2.6 kernels, /proc/mounts shows the correct fs type for"
  282.                                 echo "the device /dev/root. You can check your actual root filesystem mount type"
  283.                                 echo "there. To fix the problem, either make ext3 available at boot time by compiling"
  284.                                 echo "it statically into the kernel, or configure the correct filesystem type in"
  285.                                 echo "/etc/fstab."
  286.                             fi
  287.                         fi
  288.                         ;;
  289.                     *)
  290.                         $LM_VERBOSE && echo "Executing: mount $DEV $MP -t $FST -o remount,$OPTS$NOATIME_OPT" >> $OUTPUT
  291.                         mount $DEV $MP -t $FST -o remount,$OPTS$NOATIME_OPT
  292.                         ;;
  293.                 esac
  294.                 if [ -b $DEV -a "$CONTROL_READAHEAD" -ne 0 ] ; then
  295.                     $LM_VERBOSE && echo "Executing: /sbin/blockdev $READAHEAD_OPTION $(($LM_READAHEAD * 2)) $DEV" >> $OUTPUT
  296.                     /sbin/blockdev $READAHEAD_OPTION $(($LM_READAHEAD * 2)) $DEV >> $OUTPUT 2>&1
  297.                 fi
  298.             fi
  299.         done
  300.     fi
  301. else
  302.     # DEACTIVATE w.r.t. kernel options and mount point settings
  303.     U_AGE=$((100*$DEF_UPDATE))
  304.     B_AGE=$((100*$DEF_MAX_AGE))
  305.     set_sysctl /proc/sys/vm/laptop_mode 0
  306.     if [ -f /proc/sys/fs/xfs/age_buffer -a ! -f /proc/sys/fs/xfs/lm_age_buffer ] ; then
  307.         # These need to be restored, if there are no lm_*.
  308.         $LM_VERBOSE && echo "Restoring default XFS settings (pre-centisecs version)." >> $OUTPUT
  309.         set_sysctl /proc/sys/fs/xfs/age_buffer    $(($XFS_HZ*$DEF_XFS_AGE_BUFFER))
  310.         set_sysctl /proc/sys/fs/xfs/sync_interval $(($XFS_HZ*$DEF_XFS_SYNC_INTERVAL))
  311.     elif [ -f /proc/sys/fs/xfs/age_buffer_centisecs ] ; then
  312.         # These need to be restored as well.
  313.         $LM_VERBOSE && echo "Restoring default XFS settings." >> $OUTPUT
  314.         set_sysctl /proc/sys/fs/xfs/age_buffer_centisecs  $((100*$DEF_XFS_AGE_BUFFER))
  315.         set_sysctl /proc/sys/fs/xfs/xfssyncd_centisecs    $((100*$DEF_XFS_SYNC_INTERVAL))
  316.         set_sysctl /proc/sys/fs/xfs/xfsbufd_centisecs     $((100*$DEF_XFS_BUFD_INTERVAL))
  317.     fi
  318.     case "$KLEVEL" in
  319.         "2.4")
  320.             $LM_VERBOSE && echo "Adjusting 2.4 kernel parameters to disable laptop mode." >> $OUTPUT
  321.             set_sysctl /proc/sys/vm/bdflush "30 500 0 0 $U_AGE $B_AGE 60 20 0"
  322.             ;;
  323.         "2.6")
  324.             $LM_VERBOSE && echo "Adjusting 2.6 kernel parameters to disable laptop mode." >> $OUTPUT
  325.             set_sysctl /proc/sys/vm/dirty_writeback_centisecs   "$U_AGE"
  326.             set_sysctl /proc/sys/vm/dirty_expire_centisecs      "$B_AGE"
  327.             set_sysctl /proc/sys/vm/dirty_ratio            "$NOLM_DIRTY_RATIO"
  328.             set_sysctl /proc/sys/vm/dirty_background_ratio        "$NOLM_DIRTY_BACKGROUND_RATIO"
  329.             ;;
  330.     esac
  331.     if [ $CONTROL_MOUNT_OPTIONS -eq 1 ] ; then
  332.         $LM_VERBOSE && echo "Remounting filesystems." >> $OUTPUT
  333.         cat /etc/mtab | while read DEV MP FST OPTS DUMP PASS ; do
  334.             DO=0
  335.             case " $PARTITIONS " in
  336.                 *" $DEV "*)
  337.                     DO=1
  338.                     $LM_VERBOSE && echo "$DEV found in PARTITIONS." >> $OUTPUT
  339.                     ;;
  340.                 *)
  341.                     $LM_VERBOSE && echo "$DEV not found in PARTITIONS." >> $OUTPUT
  342.                     ;;
  343.             esac
  344.             case " $PARTITIONS " in
  345.                 *" $MP "*)
  346.                     DO=1
  347.                     $LM_VERBOSE && echo "$MP found in PARTITIONS." >> $OUTPUT
  348.                     ;;
  349.                 *)
  350.                     $LM_VERBOSE && echo "$MP not found in PARTITIONS." >> $OUTPUT
  351.                     ;;
  352.             esac
  353.             case " $PARTITIONS " in
  354.                 *" auto "*)
  355.                     $LM_VERBOSE && echo "Checking $DEV against HD because PARTITIONS contains \"auto\"." >> $OUTPUT
  356.                     for THISHD in $HD ; do
  357.                         $LM_VERBOSE && echo "   Considering $THISHD." >> $OUTPUT
  358.                         case " $DEV" in *"$THISHD"*)
  359.                             DO=1
  360.                             $LM_VERBOSE && echo "   $DEV contains $THISHD, which is in HD, so we will remount it." >> $OUTPUT
  361.                             break
  362.                             ;;
  363.                         esac
  364.                     done
  365.                     ;;
  366.             esac
  367.             if [ "$DO" -ne 0 ] ; then
  368.                 # Reset commit and atime options to defaults.
  369.                 $LM_VERBOSE && echo "Original options: $OPTS" >> $OUTPUT
  370.                 if [ "$FST" = 'unknown' ]; then
  371.                     $LM_VERBOSE && echo "Deducing fstype for $MP." >> $OUTPUT
  372.                     FST=$(deduce_fstype $MP)
  373.                     $LM_VERBOSE && echo "Deduced fstype for $MP as $FST." >> $OUTPUT
  374.                 fi
  375.                 
  376.                 # Strip stuff like ext3,ext2 into just ext3.
  377.                 $LM_VERBOSE && echo "Reducing file system type." >> $OUTPUT
  378.                 FST=${FST%%,*}
  379.                 
  380.                 # Retrieve original non-laptop mode mount options and restore them.
  381.                 # If the file that stores them doesn't exist, then laptop mode
  382.                 # has never been started.
  383.                 if [ "$WAS_ACTIVE" -ne 0 -a -f /var/run/laptop-mode-tools/nolm-mountopts ] ; then                        
  384.                     SAVED_OPTS=`grep "^$DEV " /var/run/laptop-mode-tools/nolm-mountopts`
  385.                     SAVED_OPTS=${SAVED_OPTS#* } # trim device name
  386.                 
  387.                     case "$FST" in
  388.                         "ext3"|"reiserfs"|"ext4dev"|"ext4")                                
  389.                             PARSEDOPTS="$(replace_numeric_mount_option commit commit=0 $SAVED_OPTS $OPTS)"
  390.                             PARSEDOPTS="$(replace_atime_mount_option $SAVED_OPTS $PARSEDOPTS)"
  391.                             $LM_VERBOSE && echo "Executing: mount $DEV $MP -t $FST -o remount,$PARSEDOPTS" >> $OUTPUT
  392.                             mount $DEV $MP -t $FST -o remount,$PARSEDOPTS
  393.                             ;;
  394.                         *)
  395.                             PARSEDOPTS="$(replace_atime_mount_option $SAVED_OPTS $OPTS)"
  396.                             $LM_VERBOSE && echo "Executing: mount $DEV $MP -t $FST -o remount,$PARSEDOPTS" >> $OUTPUT
  397.                             mount $DEV $MP -t $FST -o remount,$PARSEDOPTS
  398.                             ;;
  399.                     esac
  400.                 else
  401.                     $LM_VERBOSE && echo "No saved mount options, so apparently we never remounted this filesystem during this session." >> $OUTPUT
  402.                     $LM_VERBOSE && echo "Not remounting." >> $OUTPUT
  403.                 fi
  404.                 if [ -b $DEV -a "$CONTROL_READAHEAD" -ne 0 ] ; then
  405.                     $LM_VERBOSE && echo "Executing: /sbin/blockdev $READAHEAD_OPTION $(($NOLM_READAHEAD * 2)) $DEV" >> $OUTPUT
  406.                     /sbin/blockdev $READAHEAD_OPTION $(($NOLM_READAHEAD * 2)) $DEV >> $OUTPUT 2>&1
  407.                 fi
  408.             fi
  409.         done
  410.     fi
  411. fi
  412.  
  413.